using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThridGroup.ERP.DTO;
using ThridGroup.ERP.WarehouseManagement;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Uow;

namespace ThridGroup.ERP.Application.WarehouseManagement
{
    /// <summary>
    /// 赋码管理服务实现
    /// </summary>
    public class CodingmanagementService : ApplicationService, ICodingmanagementService
    {
        private readonly IRepository<CodingmanagementModel, int> _codingmanagementRepository;
        private readonly ILogger<CodingmanagementService> _logger;

        public CodingmanagementService(
            IRepository<CodingmanagementModel, int> codingmanagementRepository,
            ILogger<CodingmanagementService> logger)
        {
            _codingmanagementRepository = codingmanagementRepository;
            _logger = logger;
        }

        /// <summary>
        /// 添加赋码管理
        /// </summary>
        [UnitOfWork]
        public async Task<int> AddCodingmanagement(CreateUpdateCodingmanagementDto input)
        {
            try
            {
                _logger.LogInformation($"开始添加赋码管理：BarCode={input.BarCode}, BusinessCode={input.BusinessCode}");

                // 验证输入
                await ValidateCodingmanagementInputAsync(input);
                
                // 创建新实体
                var entity = new CodingmanagementModel
                {
                    BarCode = input.BarCode?.Trim(),
                    BarFormat = input.BarFormat?.Trim(),
                    BarTypes = input.BarTypes?.Trim(),
                    BarContext = input.BarContext?.Trim(),
                    BusinessCode = input.BusinessCode?.Trim(),
                    BusinessName = input.BusinessName?.Trim(),
                    IsNo = input.IsNo?.Trim()
                };

                _logger.LogInformation($"准备插入数据库：BarCode={entity.BarCode}, BusinessCode={entity.BusinessCode}");
                
                try
                {
                    // 使用Repository的InsertAsync方法
                    var result = await _codingmanagementRepository.InsertAsync(entity, true);
                    
                    if (result == null || result.Id <= 0)
                    {
                        throw new Exception("插入成功但未返回有效ID");
                    }
                    
                    _logger.LogInformation($"赋码管理添加成功，ID：{result.Id}");
                    return result.Id;
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库插入错误：{dbEx.Message}");
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加赋码管理失败：{ex.Message}");
                throw new Exception($"添加赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新赋码管理
        /// </summary>
        [UnitOfWork]
        public async Task<int> UpdateCodingmanagement(int id, CreateUpdateCodingmanagementDto input)
        {
            try
            {
                _logger.LogInformation($"开始更新赋码管理，ID：{id}, BarCode={input.BarCode}, BusinessCode={input.BusinessCode}");

                // 验证ID
                if (id <= 0)
                {
                    throw new ArgumentException("无效的赋码管理ID");
                }

                // 验证输入
                await ValidateCodingmanagementInputAsync(input, id);

                try
                {
                    // 先获取现有实体
                    var entity = await _codingmanagementRepository.GetAsync(id);
                    
                    if (entity == null)
                    {
                        throw new Exception($"未找到ID为{id}的赋码管理");
                    }

                    // 更新实体属性
                    entity.BarCode = input.BarCode?.Trim();
                    entity.BarFormat = input.BarFormat?.Trim();
                    entity.BarTypes = input.BarTypes?.Trim();
                    entity.BarContext = input.BarContext?.Trim();
                    entity.BusinessCode = input.BusinessCode?.Trim();
                    entity.BusinessName = input.BusinessName?.Trim();
                    entity.IsNo = input.IsNo?.Trim();

                    _logger.LogInformation($"准备更新数据库，ID：{entity.Id}");
                    
                    // 使用Repository的UpdateAsync方法
                    await _codingmanagementRepository.UpdateAsync(entity, true);
                    
                    _logger.LogInformation($"赋码管理更新成功，ID：{entity.Id}");
                    return entity.Id;
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库更新错误：{dbEx.Message}");
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新赋码管理失败：{ex.Message}");
                throw new Exception($"更新赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 删除赋码管理
        /// </summary>
        [UnitOfWork]
        public async Task DeleteCodingmanagement(int id)
        {
            try
            {
                _logger.LogInformation($"开始删除赋码管理，ID：{id}");

                // 验证ID
                if (id <= 0)
                {
                    throw new ArgumentException("无效的赋码管理ID");
                }

                try
                {
                    // 先获取现有实体
                    var entity = await _codingmanagementRepository.GetAsync(id);
                    
                    if (entity == null)
                    {
                        throw new Exception($"未找到ID为{id}的赋码管理");
                    }

                    // 进行物理删除
                    _logger.LogInformation($"准备删除数据库记录，ID：{id}");
                    await _codingmanagementRepository.DeleteAsync(entity, true);
                    
                    _logger.LogInformation($"赋码管理删除成功，ID：{id}");
                }
                catch (Exception dbEx)
                {
                    _logger.LogError(dbEx, $"数据库删除错误：{dbEx.Message}");
                    throw new Exception($"数据库操作失败：{dbEx.Message}", dbEx);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除赋码管理失败：{ex.Message}");
                throw new Exception($"删除赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取单个赋码管理
        /// </summary>
        public async Task<CodingmanagementDto> GetCodingmanagement(int id)
        {
            try
            {
                _logger.LogInformation($"开始获取赋码管理，ID：{id}");

                // 验证ID
                if (id <= 0)
                {
                    throw new ArgumentException("无效的赋码管理ID");
                }

                var entity = await _codingmanagementRepository.GetAsync(id);
                if (entity == null)
                {
                    throw new Exception($"未找到ID为{id}的赋码管理");
                }

                var result = MapToDto(entity);
                _logger.LogInformation($"获取赋码管理成功，ID：{id}");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取赋码管理失败：{ex.Message}");
                throw new Exception($"获取赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取所有赋码管理
        /// </summary>
        public async Task<List<CodingmanagementDto>> GetCodingmanagements()
        {
            try
            {
                _logger.LogInformation("开始获取所有赋码管理");

                var entities = await _codingmanagementRepository.GetListAsync();
                var results = entities.Select(MapToDto).ToList();

                _logger.LogInformation($"获取所有赋码管理成功，共{results.Count}条");
                return results;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取所有赋码管理失败：{ex.Message}");
                throw new Exception($"获取所有赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据条件获取赋码管理列表
        /// </summary>
        public async Task<List<CodingmanagementDto>> GetCodingmanagementsByCondition(string barCode, string businessCode, string businessName)
        {
            try
            {
                _logger.LogInformation($"开始根据条件获取赋码管理：barCode={barCode}, businessCode={businessCode}, businessName={businessName}");

                // 改用安全的方式获取数据
                var entities = await _codingmanagementRepository.GetListAsync();
                
                // 在内存中进行过滤，避免数据库连接被提前释放的问题
                var filteredEntities = entities.AsQueryable();
                
                // 应用条件过滤
                if (!string.IsNullOrEmpty(barCode))
                {
                    filteredEntities = filteredEntities.Where(x => x.BarTypes == barCode);
                    _logger.LogInformation($"应用条码类型过滤：{barCode}");
                }
                
                if (!string.IsNullOrEmpty(businessCode))
                {
                    filteredEntities = filteredEntities.Where(x => x.BusinessCode != null && x.BusinessCode.Contains(businessCode));
                    _logger.LogInformation($"应用业务编码过滤：{businessCode}");
                }
                
                if (!string.IsNullOrEmpty(businessName))
                {
                    filteredEntities = filteredEntities.Where(x => x.BusinessName != null && x.BusinessName.Contains(businessName));
                    _logger.LogInformation($"应用业务名称过滤：{businessName}");
                }

                // 执行查询
                var results = filteredEntities.ToList().Select(MapToDto).ToList();

                _logger.LogInformation($"根据条件获取赋码管理成功，共{results.Count}条");
                return results;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"根据条件获取赋码管理失败：{ex.Message}");
                throw new Exception($"根据条件获取赋码管理失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 检查条码是否存在
        /// </summary>
        public async Task<bool> IsBarCodeExist(string barCode, int? excludeId = null)
        {
            try
            {
                if (string.IsNullOrEmpty(barCode))
                {
                    return false;
                }

                // 获取所有数据，在内存中过滤
                var entities = await _codingmanagementRepository.GetListAsync();
                var result = entities.Any(x => x.BarCode == barCode.Trim() && 
                                           (!excludeId.HasValue || x.Id != excludeId.Value));
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查条码是否存在失败：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 检查业务编码是否存在
        /// </summary>
        public async Task<bool> IsBusinessCodeExist(string businessCode, int? excludeId = null)
        {
            try
            {
                if (string.IsNullOrEmpty(businessCode))
                {
                    return false;
                }

                // 获取所有数据，在内存中过滤
                var entities = await _codingmanagementRepository.GetListAsync();
                var result = entities.Any(x => x.BusinessCode == businessCode.Trim() && 
                                           (!excludeId.HasValue || x.Id != excludeId.Value));
                
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"检查业务编码是否存在失败：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 验证输入数据
        /// </summary>
        private async Task ValidateCodingmanagementInputAsync(CreateUpdateCodingmanagementDto input, int? id = null)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input), "赋码管理数据不能为空");
            }

            if (string.IsNullOrWhiteSpace(input.BarCode))
            {
                throw new ArgumentException("条码不能为空");
            }

            if (string.IsNullOrWhiteSpace(input.BusinessCode))
            {
                throw new ArgumentException("业务编码不能为空");
            }

            // 检查条码是否重复
            if (await IsBarCodeExist(input.BarCode, id))
            {
                throw new ArgumentException($"条码 '{input.BarCode}' 已存在");
            }

            // 检查业务编码是否重复
            if (await IsBusinessCodeExist(input.BusinessCode, id))
            {
                throw new ArgumentException($"业务编码 '{input.BusinessCode}' 已存在");
            }
        }

        /// <summary>
        /// 实体映射到DTO
        /// </summary>
        private CodingmanagementDto MapToDto(CodingmanagementModel entity)
        {
            return new CodingmanagementDto
            {
                Id = entity.Id,
                BarCode = entity.BarCode,
                BarFormat = entity.BarFormat,
                BarTypes = entity.BarTypes,
                BarContext = entity.BarContext,
                BusinessCode = entity.BusinessCode,
                BusinessName = entity.BusinessName,
                IsNo = entity.IsNo
            };
        }
    }
} 